<template>
  <div id="FormPlus">
    <el-form
      ref="ruleFormRef"
      :rules="rules"
      :inline="inline"
      :model="ruleForm"
      class="ruleForm"
      :label-width="labelWidth"
      :style="formStyle"
    >
      <div class="formBox">
        <template v-for="(item, index) in listForm">
          <template v-if="!item.type || item.type === 'input'">
            <el-form-item
              :key="index"
              :label="item.label"
              :prop="item.model"
              :required="item.required"
            >
              <el-input
                v-model.trim="ruleForm[item.model]"
                :clearable="item.clearable"
                filterable
                :placeholder="item.placeholder"
              />
            </el-form-item>
          </template>
          <template v-if="item.type === 'select'">
            <el-form-item
              :key="index"
              :label="item.label"
              :prop="item.model"
              :required="item.required"
            >
              <el-select
                :style="`width: ${formItemContentWidth}`"
                v-model.trim="ruleForm[item.model]"
                :clearable="item.clearable === undefined || item.clearable"
                filterable
                :placeholder="item.placeholder || ''"
                @change="item.isSelectChange ? submitForm(ruleFormRef) : ''"
              >
                <el-option
                  v-for="itemSon in item.options"
                  :key="itemSon.value"
                  :label="itemSon.label"
                  :value="itemSon.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </template>
          <template v-if="item.type === 'date-picker'">
            <el-form-item
              :key="index"
              :prop="item.model"
              :label="item.label"
              :required="item.required"
            >
              <el-date-picker
                :style="`width: ${formItemContentWidth}`"
                v-model.trim="ruleForm[item.model]"
                :clearable="item.clearable === undefined || item.clearable"
                :type="item.pickerType"
                :placeholder="item.placeholder"
                :format="item.format"
                :value-format="item.valueFormat"
                :shortcuts="item.shortcuts"
              />
            </el-form-item>
          </template>
          <template v-if="item.type === 'datetimerange'">
            <el-form-item
              :key="index"
              :prop="item.model"
              :label="item.label"
              :required="item.required"
            >
              <el-date-picker
                v-model.trim="ruleForm[item.model]"
                type="datetimerange"
                :format="item.format"
                :value-format="item.valueFormat"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
              >
              </el-date-picker>
            </el-form-item>
          </template>
          <template v-if="item.type === 'radioButton'">
            <el-form-item
              :key="index"
              :prop="item.model"
              :label="item.label"
              :required="item.required"
            >
              <el-radio-group v-model="ruleForm[item.model]">
                <el-radio-button
                  v-for="(itemRadio, index) in item.itemRadioList"
                  :key="index"
                  :label="itemRadio"
                ></el-radio-button>
              </el-radio-group>
            </el-form-item>
          </template>
          <template v-if="item.type === 'radio'">
            <el-form-item
              :key="index"
              :prop="item.model"
              :label="item.label"
              :required="item.required"
            >
              <el-radio-group v-model="ruleForm[item.model]">
                <el-radio
                  v-for="(itemRadio, index) in item.itemRadioList"
                  :key="index"
                  :label="itemRadio"
                  :border="item.borderHideOrShow"
                ></el-radio>
              </el-radio-group>
            </el-form-item>
          </template>
        </template>
      </div>
      <slot ref="FormLocal"></slot>
    </el-form>
  </div>
</template>

<script lang="ts" setup>
import {
  reactive,
  ref,
  computed,
  PropType,
  onMounted,
  defineExpose,
} from "vue";
import type { FormInstance } from "element-plus";
import { getCurrentInstance, ComponentInternalInstance } from "vue";

export interface options {
  value: string;
  label: string;
}

export interface FormProps {
  // 表单类型
  type?: string;
  // 表单名
  label: string;
  // 绑定的字段
  model: string;
  // 是否必填
  required?: boolean;
  // 输入框  是否有清空
  clearable?: boolean;
  // 提示
  placeholder?: string;
  // 下拉框的 选项
  options?: Array<options>;
  // 时间选项
  pickerType?: any;
  // 时间选项的 格式自定义
  format?: string;
  // 获取出来的值得格式
  valueFormat?: string;
  // 判断下拉框是否需要下拉事件
  isSelectChange?: boolean;
  // 快捷选择日期
  shortcuts?: Array<{
    text: string;
    value: Function | string | Date;
  }>;
  // 单选列表
  itemRadioList?: Array<string>;
  // 单选列表是否为border radio 类型的
  borderHideOrShow?: boolean;
}

// 接受props
const props = defineProps({
  rules: {
    type: Object,
    default: () => {},
  },
  formItemContentWidth: {
    type: String,
    default: "165px",
  },
  listForm: {
    // type: Array as PropType<FormProps[]>,
    type: Array as any,
    default: () => [],
  },
  inline: {
    type: Boolean,
    default: false,
  },
  labelWidth: {
    type: String,
    default: "70px",
  },
  //  表单的默认值
  defaultSlotValue: {
    type: Object,
    default: {},
  },
});
// ref 表单实例
const ruleFormRef = ref<FormInstance>();

// 自定义事件
const emit = defineEmits(["submitFormValue"]);
// 表单数据
let ruleForm: any = reactive({});
// 表单默认值
const defaultValueLocal = props.defaultSlotValue;
// 计算父组件穿过来的元素宽度
const formStyle = computed(() => {
  return {
    "--formItemContentWidth": props.formItemContentWidth,
  };
});
// 所填写数据
const submitForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.validate((valid) => {
    if (!valid) {
      return;
    }
    const exportData = { ...ruleForm };
    emit("submitFormValue", exportData);
  });
};
//获取bus 实例
const Instance = getCurrentInstance()!;
// 加载前
onMounted(() => {
  // console.log("defaultValueLocal", props.defaultSlotValue);

  for (const key in defaultValueLocal) {
    ruleForm[key] = JSON.parse(JSON.stringify(defaultValueLocal[key]));
  }
  // 订阅事件
  Instance.appContext.config.globalProperties.$bus.on("resetForm", () => {
    ruleFormRef.value?.resetFields();
  });
});
const formDataL = () => {
  return ruleForm;
};
//这里需要暴露出去不然父组件调用不到这个方法
defineExpose({ ruleForm, formDataL });
</script>

<style lang="scss" scoped>
#FormPlus {
  .ruleForm {
    width: 100%;
    .formBox {
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
      ::v-deep.el-form-item__content {
        width: var(--formItemContentWidth);
      }
      ::v-deep.el-form-item__content .el-date-editor,
      .el-input {
        width: var(--formItemContentWidth);
      }
    }
  }
  .btn-container {
    display: flex;
    justify-content: flex-end;
  }
}
</style>
